/*
 * 础光实时操作系统PhotonRTOS -- 计数器功能测试代码
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Lin Yang <s-yanglin@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include "../functest.h"

#define IdCounter		2
#define IdWaiter0		0
#define IdWaiter1		1
#define IdWaiter2		2
#define TicksPerBase		2
#define Waiter_Callback_0	100
#define Waiter_Callback_1	(Waiter_Callback_0 + 1)
#define Waiter_Callback_2	(Waiter_Callback_0 + 2)

FUNC(void, OS_CODE) waiter_callback_for_test(
	VAR(OsWaiterRefType, AUTOMATIC) waiter_ref);

VAR(uint8, AUTOMATIC) counter_sequence_right[MAX_SEQUENCE] = {
	1, 2, Waiter_Callback_0, 3, Waiter_Callback_1, 4,
	Waiter_Callback_2, 5, 6, Waiter_Callback_0,
	Waiter_Callback_1, 7, 8, 9, Waiter_Callback_1, 10,
	Waiter_Callback_0, 11, 12, Waiter_Callback_1, SEQUENCE_END,
};

TEST(counter)
{
	VAR(int32_t, AUTOMATIC) i, j;

	DeclareCounter(IdCounter, 1024, TicksPerBase, 1, SOFTWARE);
	DeclareWaiter(IdWaiter0, 2, 4, IdCounter, &waiter_callback_for_test, NULL_PTR);
	DeclareWaiter(IdWaiter1, 3, 3, IdCounter, &waiter_callback_for_test, NULL_PTR);
	DeclareWaiter(IdWaiter2, 4, 0, IdCounter, &waiter_callback_for_test, NULL_PTR);

	LOGI("计数器功能测试开始\n");
	LOGI("waiter0将在value2启动,每经过4个value回调一次'\n");
	LOGI("  即: 将在value2,6,10时回调并输出'waiter0'\n");
	LOGI("waiter1将在value3启动,每经过3个value回调一次\n");
	LOGI("  即: 将在value3,6,9,12时回调并输出'waiter3'\n");
	LOGI("waiter3将在value4启动,之后不回调\n");
	LOGI("  即: 将在value4时回调并输出'waiter3'\n");

	for (i = 1; i <= 12; i++) {
		SEQUENCE_RECORD_VALUE(i, "");
		printk("value%d\t:", i);
		for (j = 0; j < TicksPerBase; j++)
			IncrementCounter(IdCounter);
		printk("\n");
	}

	ASSERT_SEQUENCE(counter_sequence_right);
	remove_waiter_from_counter(&autosar_waiters[IdWaiter0], IdCounter);
	remove_waiter_from_counter(&autosar_waiters[IdWaiter1], IdCounter);
	remove_waiter_from_counter(&autosar_waiters[IdWaiter2], IdCounter);
}

FUNC(void, OS_CODE) waiter_callback_for_test(
	VAR(OsWaiterRefType, AUTOMATIC) waiter_ref)
{
	SEQUENCE_RECORD_VALUE(get_waiter_id(waiter_ref) + Waiter_Callback_0, "");
	printk("\twaiter%d", get_waiter_id(waiter_ref));
}

TEST_SUIT(counter)
{
	FUNCTEST_CASE(counter);
}

